#include <iostream>
#include "frame.h"
#include <sstream>
#include <bitset>
#include <vector>
#include <iomanip>
#include <stack>
#include <cmath>
using namespace std;
using namespace can;
//返回0测试全部通过
//返回非0表示未通过的测试数量
int main()
{
    int ret=0;
    //一、内部函数模块测试
    //CRC校验计算测试
    vector<unsigned char> d;
    d.push_back('x');
    d.push_back('y');
    d.push_back('x');
    d.push_back('-');
    d.push_back('t');
    d.push_back('e');
    d.push_back('s');
    d.push_back('t');
    frame a(bitset<11> ("11110000010"),d);
    a.fmt.set(fmt_e::hex);
    a.fmt.set(crc);
    {
        ostringstream ts;
        ts<<a;
        string ans("1e0843a39b2ba16bc3cbc6e38");    //经手动验证过的CRC校验序列
        if(ans!=ts.str())   
        {
            ++ret;
            cerr<<setw(2)<<ret<<": failed CRC calculation\n";
        }
    }
    //输出函数测试
    a.fmt.reset();
    {
        size_t top_num=pow(2,a.fmt.size());
        cout<<"=====output function test====="<<endl;
        for(int i=0;i<top_num;++i)
        {
            a.fmt=bitset<a.fmt.size()> (i);
            cout<<a.fmt<<'\t'<<a<<'\n';
        }
        cout<<"=====total "<<top_num<<"output formates======"<<endl;
    }
    a.fmt.reset();
    //二、基本功能测试
    //测试标准帧的收发
    {
        ostringstream ts;
        try
        {
            ts<<a;
            frame b(ts.str());
            if(!b.isACK() || a!=b)
            {
                ++ret;
                cerr<<setw(2)<<ret<<": failed standard base frame send/recv test \n";
            }
        }
        catch(const std::exception& e)
        {
            std::cerr << e.what() << '\n';
            ++ret;
            cerr<<setw(2)<<ret<<": failed standard base frame send/recv test \n";
        }            
    }
    //测试扩展帧的收发
    {
        ostringstream ts;
        try
        {
            frame ea(bitset<29> ("10010101010001000001100000111"),d);
            ts<<ea;
            frame eb(ts.str());
            if(!eb.isACK() || ea!=eb)
            {
                ++ret;
                cerr<<setw(2)<<ret<<": failed extended base frame send/recv test \n";
            }
        }
        catch(const std::exception& e)
        {
            std::cerr << e.what() << '\n';
            ++ret;
            cerr<<setw(2)<<ret<<": failed extended base frame send/recv test \n";
        }            
    }
    //测试远程帧请求标准帧
    {
        ostringstream ts,rs;
        try
        {
            frame ra(bitset<11> ("11001100011"),8);
            ts<<ra;
            frame sa(ts.str());
            if(!sa.isACK())
                throw logic_error("CRC error while receiving RTR frame");
            int data_size;
            if(sa.isRTR(&data_size))
            {
                sa.fillData(d);
                rs<<sa;
                frame ra_1(rs.str()),ra_2(bitset<11> ("11001100011"),d);
                if(ra_1!=ra_2)
                    throw logic_error("recv and send frames are different!");
            }else
                throw logic_error("How this can not be a RTR frame");
        }
        catch(const std::exception& e)
        {
            std::cerr << e.what() << '\n';
            ++ret;
            cerr<<setw(2)<<ret<<": failed remote base frame send/recv test \n";
        }            
    }
    //测试远程帧请求扩展帧
    {
        ostringstream ts,rs;
        try
        {
            frame ra(bitset<29> ("10110101111000011110011111011"),8);
            ts<<ra;
            frame sa(ts.str());
            if(!sa.isACK())
                throw logic_error("CRC error while receiving RTR frame");
            int data_size;
            if(sa.isRTR(&data_size))
            {
                sa.fillData(d);
                rs<<sa;
                frame ra_1(rs.str()),ra_2(bitset<29> ("10110101111000011110011111011"),d);
                if(ra_1!=ra_2)
                    throw logic_error("recv and send frames are different!");
            }else
                throw logic_error("How this can not be a RTR frame");
        }
        catch(const std::exception& e)
        {
            std::cerr << e.what() << '\n';
            ++ret;
            cerr<<setw(2)<<ret<<": failed remote extended frame send/recv test \n";
        }            
    }
    //边界测试
    //自顶向下输入测试
    //自底向上输入测试
    return 0;   
} 